package com.bbzn.device.client.service.emq.data;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bbzn.device.client.config.EmqCode;
import com.bbzn.device.client.dataobject.Device;
import com.bbzn.device.client.dataobject.LocusCoordinate;
import com.bbzn.device.client.dto.api.ResultResponse;
import com.bbzn.device.client.dto.api.position.GetPositionRequest;
import com.bbzn.device.client.dto.api.position.GetPositionResult;
import com.bbzn.device.client.dto.device.DevicePopupDTO;
import com.bbzn.device.client.dto.gps.GpsPosition;
import com.bbzn.device.client.dto.gps.GpsResult;
import com.bbzn.device.client.dto.position.WifiPosition;
import com.bbzn.device.client.service.*;
import com.bbzn.device.client.service.emq.alarm.EmqBaseAlarm;
import com.bbzn.device.client.utils.BabaBeanUtils;
import com.bbzn.device.client.utils.GPSUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author: jncehuang
 * @Date : 2021/4/9 11:14
 * @Version 1.0
 * NB 定位
 */
@Slf4j
@Component
public class EmqNbGpsContinueStrategy extends EmqBaseAlarm implements EmqStrategy {
    @Autowired
    DeviceService deviceService;

    @Autowired
    GaodeMapApiService gaodeMapApiService;

    @Autowired
    private PublishService publishService;

    @Autowired
    private LocusCoordinateMongoService locusCoordinateMongoService;

    @Override
    public String emqAction(String payLoad) {
        try {
            GpsResult res =JSON.parseObject(payLoad, new TypeReference<GpsResult>() {});
            if(null==res || StringUtils.isEmpty(res.getImei())){
                return "json解析错误";
            }
            Device device = null;
            //先使用GDS
            if(CollectionUtils.isNotEmpty(res.getMessages())){
                log.info("进入GDS解析");
                List<Device> deviceList = res.getMessages().stream().map(r->getOnePosition(r,res.getImei())).filter(Objects::nonNull).collect(Collectors.toList());
                if(CollectionUtils.isNotEmpty(deviceList)){
                    deviceList.stream().sorted(Comparator.comparing(Device::getGps));
                    device = deviceList.get(0);
                    log.info("GDS解析完成");
                }
            }
            //最终会使用GDS
            if(CollectionUtils.isNotEmpty(res.getWifis())){
                log.info("进入WIFI定位解析");
                GetPositionRequest request = new GetPositionRequest();
                request.setImei(res.getImei());
                request.setOutput("json");
                request.setAccesstype(1);
                String macInfo = res.getWifis().stream().map(this::getMacInfo).filter(Objects::nonNull).collect(Collectors.joining("|", "", ""));
                request.setMacs(macInfo);
                request.setMmac(macInfo);
                ResultResponse<GetPositionResult> response = gaodeMapApiService.getPosition(request);
                if (null != response.getData() && response.getData().getStatus().equals("1") &&
                        StringUtils.isNotEmpty(response.getData().getResult().getLocation()) &&
                        StringUtils.isNotEmpty(response.getData().getResult().getDesc())) {
                    device = new Device();
                    device.setImei(res.getImei());
                    device.setLocation(response.getData().getResult().getDesc());
                    String lon = response.getData().getResult().getLocation().split(",")[0];
                    String lat = response.getData().getResult().getLocation().split(",")[1];
                    device.setLon(lon);
                    device.setLat(lat);
                }
                log.info("WIFI定位请求成功");
            }
            if(null==device){
                log.info("NB定位失败");
                return "GDS定位失败！";
            }
            deviceService.updateByImeiSelective(device);
            LocusCoordinate locusCoordinate = BabaBeanUtils.voToDto(device, LocusCoordinate.class);
            locusCoordinate.setCreateTime(System.currentTimeMillis());
            locusCoordinateMongoService.recordJob(locusCoordinate);
            log.info("NB定位完成");

            DevicePopupDTO pop = deviceService.selDevicePopup(res.getImei());
            // 定位消息统一推送给web前端
            // 组装json
            JSONObject data = new JSONObject();
            data.put("battery", pop.getBattery());
            data.put("code", EmqCode.gpsContinueCode);
            data.put("lon", pop.getLon());
            data.put("lat", pop.getLat());
            data.put("name", pop.getName());
            data.put("imei", pop.getImei());
            data.put("headImg", pop.getHeadImg());
            data.put("time", System.currentTimeMillis());
            publishService.sendToMqtt(data.toJSONString(), "sfwatch/" + pop.getImei() + "/client");

        } catch (Exception e) {
            e.printStackTrace();
            return "WIFI定位失败！";
        }
        return JSON.toJSONString(payLoad);
    }

    private Device getOnePosition(GpsPosition gpsPosition, String imei){
        Device device = new Device();
        String latStr = gpsPosition.getGngga().split(",")[2];
        String lonStr = gpsPosition.getGngga().split(",")[4];
        if(StringUtils.isEmpty(latStr) || StringUtils.isEmpty(lonStr)){
            return null;
        }
        String lon = GPSUtils.DDDmTurnD(lonStr);
        String lat = GPSUtils.DDmTurnD(latStr);
        device.setLon(lon);
        device.setLat(lat);
        device.setImei(imei);
        String gdsStr = gpsPosition.getGpgsa().split(",")[4];
        if(StringUtils.isEmpty(gdsStr)){
            gdsStr = "0";
        }
        Integer gds = Integer.parseInt(gdsStr);
        device.setGps(gds);
        return device;
    }

    private String getMacInfo(WifiPosition position) {
        if (null == position || StringUtils.isEmpty(position.getMac())
                || StringUtils.isEmpty(position.getSignal()) || StringUtils.isEmpty(position.getSsid())) {
            return null;
        }
        StringBuilder macStr = new StringBuilder(position.getMac());
        macStr.append(",");
        macStr.append(position.getSignal());
        macStr.append(",");
        macStr.append(position.getSsid());
        return macStr.toString();
    }
}
